package 多线程3;
//这个包包含了很多和多线程操作相关的组件,简称JUC(java.util.concurrent)

//多线程案例
//--

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * 阻塞队列:线程安全的队列
 * 如果当前队列为空,尝试出队列,就会发生阻塞,一直阻塞到队列里元素不空
 * 如果当前队列满了,尝试入队列,也会产生阻塞,一直阻塞到队列里的元素不满为止
 *
 * 无锁队列:线程安全的队列
 * 不是通过锁的方式保证线程安全
 */

//Java标准库里内置了一个BlockingQueue这样的类来实现了阻塞队列的功能,用法和普通的队列很相似:入队列,出队列,(没有取队首元素)
public class TestDemo2 {
    public static void main(String[] args) throws InterruptedException {
        //此处可以看到LinkedBlockingQueue内部是基于链表来实现的(Queue也是可基于LinkedList来实现的)
        BlockingQueue<String>  queue = new LinkedBlockingDeque<>(10);//可以指定一个最大容量,如果没给,会自动扩容
        queue.put("hello");//put操作,可能会尝试阻塞,如果是阻塞的话,有可能通过这个异常来把这个阻塞的状态去打破
        //queue.offer("hello");为什么不用这个呢,因为put带有阻塞功能,而offer不带有阻塞功能.使用阻塞队列一般都是使用put

        String elem = queue.take();//取队首元素,take()也是带有阻塞功能的
        System.out.println(elem);
        //此时队列为空,如果再次取队列元素,则会触发阻塞功能
        elem = queue.take();//代码执行到这里就不走了,一直等到有其他线程给这个队列里放新元素为止
        System.out.println(elem);
    }

    //上面只是助于理解的一个简单例子
    //有了阻塞队列之后,可以用来实现"生产者消费者模型"
    //生产者和消费者之间还需要一个重要角色,即交易场所
    //计算机中,生产者就是一组线程,消费者也是另一组线程.交易场所就可以是阻塞队列了.
    //生产者消费者模型是在服务器开发中非常常用有用的一种编程手段
    //追求高内聚,低耦合
    //最大的用途:
    // 1.解耦合
    //--
    // 2.削峰填谷
    //--
}
